package com.anrong.wulansdk.sdk.utils;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;

import com.xdja.sslvpn.api.VpnApi;
import com.xdja.sslvpn.api.VpnManager;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.UUID;

/**
 * 工具类
 * @author cxy
 *
 */
public class Utils {
	public static TelephonyManager mTelephonyMgr;
	protected static UUID uuid;
	private VpnApi vpnApi = null;
	public static String imei;
	/** 
	 * 是否联网
	 *  
	 * @param context 
	 * @return 
	 */  
	public static boolean isNetworkAvailable(Context context) {
		ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
		NetworkInfo[] info = mgr.getAllNetworkInfo();  
		if (info != null) {  
			for (int i = 0; i < info.length; i++) {  
				if (info[i].getState() == NetworkInfo.State.CONNECTED) {
					MyLogcat.log("network is available");
					return true;
				}
			}  
		}  
		MyLogcat.log("network is not available");
		return false;  
	}

	/**
	 * 获取当前的UTC时间
	 * @return
	 */
	public static String getCurrentUTCTime(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
		return sdf.format(new Date());
	}
	
	
	/**
	 * date转为UTC date
	 * @param date
	 * @return
	 */
	public static Date trans2UTC(Date date){
		java.util.Calendar cal = java.util.Calendar.getInstance();

		int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);

		int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);
		cal.setTime(date);

		cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
		return cal.getTime();
	}

	/**
	 * 获取IMEI
	 */
	public static String getImei(Context context) {
		TelephonyManager mTelephonyMgr = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
//		return mTelephonyMgr.getDeviceId();
		return  "111111111111111";
//		mTelephonyMgr.getLine1Number();//获取电话号码
	}

	/***
	 * 获取
	 * @param context
	 * @return
	 */
	public static String getIMEI(Context context) {

			if (mTelephonyMgr == null) {
				mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			}else{
				imei = mTelephonyMgr.getDeviceId();
			}
			return imei;

	}
	
	/**
	 * 获取版本名称 versionName例如1.0
	 * @return
	 */
	public static String getVersionName(Context c){
		String versionName = "";
		try {
			PackageManager pm = c.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
			versionName = pi.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionName;
	}
	
	
	/**
	 * 获取版本编号 versionCode 例如1
	 * @return
	 */
	public static String getVersionCode(Context c){
		String versionCode = "";
		try {
			PackageManager pm = c.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(c.getPackageName(), 0);
			versionCode = pi.versionCode+"";
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionCode;
	}
	
	public static String getPackageName(Context c){
		return c.getPackageName();
	}
	
	/**
	 * 获取mac
	 * @param c
	 * @return
	 */
	public static String getMac(Context c){
		/*获取mac地址有一点需要注意的就是android 6.0版本后，以下注释方法不再适用，不管任何手机都会返回"02:00:00:00:00:00"这个默认的mac地址，这是googel官方为了加强权限管理而禁用了getSYstemService(Context.WIFI_SERVICE)方法来获得mac地址。*/
		//        String macAddress= "";
		//		        WifiManager wifiManager = (WifiManager) MyApp.getContext().getSystemService(Context.WIFI_SERVICE);
		//		        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
		//		        macAddress = wifiInfo.getMacAddress();
		//		        return macAddress;

		String macAddress = null;
		StringBuffer buf = new StringBuffer();
		NetworkInterface networkInterface = null;
		try {
			networkInterface = NetworkInterface.getByName("eth1");
			if (networkInterface == null) {
				networkInterface = NetworkInterface.getByName("wlan0");
			}
			if (networkInterface == null) {
				return "02:00:00:00:00:02";
			}
			byte[] addr = networkInterface.getHardwareAddress();
			for (byte b : addr) {
				buf.append(String.format("%02X:", b));
			}
			if (buf.length() > 0) {
				buf.deleteCharAt(buf.length() - 1);
			}
			macAddress = buf.toString();
		} catch (SocketException e) {	
			e.printStackTrace();
			return "02:00:00:00:00:02";
		}
		return macAddress;
	}

	/**
	 *  获取ip
	 * @param c
	 * @return
	 */
	public static String getIP(Context c){
		// WiFi未连接的情况下，无法获取IP
		String ip = null;
		WifiManager wifiMgr = (WifiManager)c.getSystemService(Context.WIFI_SERVICE);  
		
		// 检查Wifi状态  
        if (!wifiMgr.isWifiEnabled())
        	return getIPAddress(true);
        
		WifiInfo info = (null == wifiMgr ? null : wifiMgr.getConnectionInfo());  
		if (null != info) {  
			ip = int2ip(info.getIpAddress());
		}
		return ip;
	}

	/**
	 * ip转换
	 * @param ipInt
	 * @return
	 */
	public static String int2ip(long ipInt) {  
		StringBuilder sb = new StringBuilder();  
		sb.append(ipInt & 0xFF).append(".");  
		sb.append((ipInt >> 8) & 0xFF).append(".");  
		sb.append((ipInt >> 16) & 0xFF).append(".");  
		sb.append((ipInt >> 24) & 0xFF);  
		return sb.toString();  
	}
	
	/** 
     * Get IP address from first non-localhost interface 
     * 
     * @param useIPv4 true=return ipv4, false=return ipv6 
     * @return address or empty string 
     */ 
	public static String getIPAddress(boolean useIPv4) {  
        try {  
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());  
            for (NetworkInterface intf : interfaces) {  
                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());  
                for (InetAddress addr : addrs) {  
                    if (!addr.isLoopbackAddress()) {  
                        String sAddr = addr.getHostAddress().toUpperCase();  
//                        boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                        boolean isIPv4;
                    	isIPv4 = addr instanceof Inet4Address;
//							isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                        if (useIPv4) {  
                            if (isIPv4)  
                                return sAddr;  
                        } else {  
                            if (!isIPv4) {  
                                int delim = sAddr.indexOf('%'); // drop ip6 port suffix  
                                return delim < 0 ? sAddr : sAddr.substring(0, delim);  
                            }  
                        }  
                    }  
                }  
            }  
        } catch (Exception ex) {  
        }  
        return "";  
    }
	
	
	/**
	 * 工作线程
	 * @param r
	 */
	public static void post(Runnable r){
		new Thread(r).start();
	}
	
	
	/**
	 * 获取当前设备机型
	 * @return
	 */
	public static String getModel(){
		return Build.MODEL;
	}
	
	/**
	 * 获取当前设备操作系统
	 * @return
	 */
	public static String getOS(){
		return Build.VERSION.RELEASE;
	}
	
	
	
	//这个是获取SHA1的方法
	public static String getCertificateSHA1Fingerprint(Context context) {
		//获取包管理器
		PackageManager pm = context.getPackageManager();
		//获取当前要获取SHA1值的包名，也可以用其他的包名，但需要注意，
		//在用其他包名的前提是，此方法传递的参数Context应该是对应包的上下文。
		String packageName = context.getPackageName();
		//返回包括在包中的签名信息
		int flags = PackageManager.GET_SIGNATURES;
		PackageInfo packageInfo = null;
		try {
			//获得包的所有内容信息类
			packageInfo = pm.getPackageInfo(packageName, flags);
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
		//签名信息
		Signature[] signatures = packageInfo.signatures;
		byte[] cert = signatures[0].toByteArray();
		//将签名转换为字节数组流
		InputStream input = new ByteArrayInputStream(cert);
		//证书工厂类，这个类实现了出厂合格证算法的功能
		CertificateFactory cf = null;
		try {
			cf = CertificateFactory.getInstance("X509");
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		//X509证书，X.509是一种非常通用的证书格式
		X509Certificate c = null;
		try {
			c = (X509Certificate) cf.generateCertificate(input);
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		String hexString = null;
		try {
			//加密算法的类，这里的参数可以使MD4,MD5等加密算法
			MessageDigest md = MessageDigest.getInstance("SHA1");
			//获得公钥
			byte[] publicKey = md.digest(c.getEncoded());
			//字节到十六进制的格式转换
			hexString = byte2HexFormatted(publicKey);
		} catch (NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (CertificateEncodingException e) {
			e.printStackTrace();
		}
		return hexString;
	}
	
	
	//这里是将获取到得编码进行16进制转换
	private static String byte2HexFormatted(byte[] arr) {
		StringBuilder str = new StringBuilder(arr.length * 2);
		for (int i = 0; i < arr.length; i++) {
			String h = Integer.toHexString(arr[i]);
			int l = h.length();
			if (l == 1)
				h = "0" + h;
			if (l > 2)
				h = h.substring(l - 2, l);
			str.append(h.toUpperCase());
			if (i < (arr.length - 1))
				str.append(':');
		}
		return str.toString();
	}
	
	
	
	
	/** 
	 * 判断某个服务是否正在运行的方法 
	 *  
	 * @param mContext 
	 * @param serviceName 
	 *            是包名+服务的类名（例如：net.loonggg.testbackstage.TestService） 
	 * @return true代表正在运行，false代表服务没有正在运行 
	 */  
	public static boolean isServiceWork(Context mContext, String serviceName) {  
	    boolean isWork = false;  
	    ActivityManager myAM = (ActivityManager) mContext  
	            .getSystemService(Context.ACTIVITY_SERVICE);  
	    List<RunningServiceInfo> myList = myAM.getRunningServices(40);  
	    if (myList.size() <= 0) {  
	        return false;  
	    }  
	    for (int i = 0; i < myList.size(); i++) {  
	        String mName = myList.get(i).service.getClassName().toString();  
	        if (mName.equals(serviceName)) {  
	            isWork = true;
	            break;  
	        }  
	    }  
	    return isWork;  
	}  
	
	
	/**
     * 返回运营商 需要加入权限 <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <BR>
     * 
     * @return 中国移动，中国联通，中国电信，未知
     */
	public static String getOperators(Context context) {
        // 移动设备网络代码（英语：Mobile Network Code，MNC）是与移动设备国家代码（Mobile Country Code，MCC）（也称为“MCC /
        // MNC”）相结合, 例如46000，前三位是MCC，后两位是MNC 获取手机服务商信息
        String OperatorsName = "未知";
        TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String IMSI =  manager.getSubscriberId();
        if (IMSI == null) {
			return "未知";
		}
        // IMSI号前面3位460是国家，紧接着后面2位00 运营商代码
        if (IMSI.startsWith("46000") || IMSI.startsWith("46002") || IMSI.startsWith("46007")) {
            OperatorsName = "中国移动";
        } else if (IMSI.startsWith("46001") || IMSI.startsWith("46006")) {
            OperatorsName = "中国联通";
        } else if (IMSI.startsWith("46003") || IMSI.startsWith("46005")) {
            OperatorsName = "中国电信";
        }else {
			OperatorsName = "未知";
		}
        return OperatorsName;
    }
	
	
	/**
	 * 获取网络类型
	 * @param context
	 * @return 2G/3G/4G/Wi-Fi
	 */
	public static String getNetwork(Context context){
		NetworkInfo network = ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
		
		String strNetwork = "未知";
		
		if (network != null && network.isAvailable() && network.isConnected()) {
			int type = network.getType();
			
			if (type == ConnectivityManager.TYPE_WIFI) {
				strNetwork = "Wi-Fi";
			}else if (type == ConnectivityManager.TYPE_MOBILE) {
				int networkType = network.getSubtype();
				switch (networkType) {
					case TelephonyManager.NETWORK_TYPE_GPRS:
					case TelephonyManager.NETWORK_TYPE_EDGE:
					case TelephonyManager.NETWORK_TYPE_CDMA:
					case TelephonyManager.NETWORK_TYPE_1xRTT:
					case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11
						strNetwork = "2G";
						break;
					case TelephonyManager.NETWORK_TYPE_UMTS:
					case TelephonyManager.NETWORK_TYPE_EVDO_0:
					case TelephonyManager.NETWORK_TYPE_EVDO_A:
					case TelephonyManager.NETWORK_TYPE_HSDPA:
					case TelephonyManager.NETWORK_TYPE_HSUPA:
					case TelephonyManager.NETWORK_TYPE_HSPA:
					case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9 : replace by 14
					case TelephonyManager.NETWORK_TYPE_EHRPD: //api<11 : replace by 12
					case TelephonyManager.NETWORK_TYPE_HSPAP: //api<13 : replace by 15
						strNetwork = "3G";
						break;
					case TelephonyManager.NETWORK_TYPE_LTE:  //api<11 : replace by 13
						strNetwork = "4G";
						break;
				}
			}
		}
		return strNetwork;
	}

	/**
	 *
	 * @Title: getDeviceUUID @Description:加密算法过后的设备ID，与设备无关，只做唯一约束性
	 *         设备管理应该直接用设备ID @param @return 设定文件 @return String 返回类型 @throws
	 */
	public String getDeviceUUID(Context context) {

			final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
			try {
				if (!"9774d56d682e549c".equals(androidId)) {
					uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
				} else {
					if (mTelephonyMgr == null) {
						mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
					}
					final String deviceId = mTelephonyMgr.getDeviceId();
					uuid = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
				}
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}

			// Write the value out to the prefs file
			String uid = uuid.toString().replace("-", "");
			return uid;
		}
	/**
	 * 获取安全客户端id
	 *
	 * @return
	 */
	public String getCardId(Context context) {
		String cardID = null;
		if(vpnApi==null){
			vpnApi = VpnManager.getVPNInstance(context);
		}else{
			cardID = vpnApi.getCardID();
		}

		return cardID;
	}


}
